package com.csun.cmny.provider.device.phone;

import com.csun.cmny.provider.device.phone.entity.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2019-02-19 13:34
 * @Description: the phone message decoder
 */
@Slf4j
@Component
public class PhoneMessageDecoder {

    /**
     * phone message parse data entity
     *
     * @param msg   phone message
     *
     * @return  phone message data entity
     */
    public PhoneMessageDataEntity parse(byte[] msg) {

        PhoneMessageDataEntity phoneMsgDate = new PhoneMessageDataEntity();

        int length = msg.length;
        // 验证长度
        if (length < 7) {
            log.warn("phone msg length {} error ", length);
            return null;
        }

        // 验证head
        if (msg[0] != PhoneConstant.PHONE_HEAD) {
           log.warn("phone msg [0] {} not {}", msg[0], PhoneConstant.PHONE_HEAD);
           return null;
        }

        // 验证end2
        if (msg[length - 1] != PhoneConstant.PHONE_END_2) {
            log.warn("phone msg [length - 1] {} not {}", msg[length - 1], PhoneConstant.PHONE_END_2);
            return null;
        }

        // 验证end1
        if (msg[length - 2] != PhoneConstant.PHONE_END_1) {
            log.warn("phone msg [length - 2] {} not {}", msg[length - 2], PhoneConstant.PHONE_END_1);
            return null;
        }

        // 高位  --   低位
        short msg_length = (short)(((msg[3] & 0x00FF) << 8) | (0x00FF & msg[2]));
        int msg_length_req = 4 + msg_length + 2;

        // 验证消息内容长度
        if (length != msg_length_req) {
            log.warn("phone msg length {} not {} error", length, msg_length_req);
            return null;
        }
        byte[] data = new byte[msg_length];
        System.arraycopy(msg, 4, data, 0, msg_length);

        phoneMsgDate.setDsize(msg_length);
        phoneMsgDate.setData(data);

        return phoneMsgDate;
    }

    /**
     * phone message data entity parse login entity
     *
     * @param phoneMsg  phone message data entity
     *
     * @return  phone message data login entity
     */
    public PhoneMessageDataLoginEntity parseLogin(PhoneMessageDataEntity phoneMsg) {

        PhoneMessageDataLoginEntity phoneMessageDataLoginEntity = new PhoneMessageDataLoginEntity();
        if (phoneMsg == null) {
            return null;
        }

        if (PhoneConstant.PHONE_DATA_TYPE_LOGIN_REQ != phoneMsg.getData()[0]) {
            log.warn("phone msg not login req {}", phoneMsg.getData()[0]);
            return null;
        }

        phoneMessageDataLoginEntity.setDeviceType(phoneMsg.getData()[1]);
        phoneMessageDataLoginEntity.setDeviceStatus(phoneMsg.getData()[2]);
        System.arraycopy(phoneMsg.getData(), 3, phoneMessageDataLoginEntity.getUserId(), 0, 16);
        System.arraycopy(phoneMsg.getData(), 19, phoneMessageDataLoginEntity.getDeviceId(), 0, 8);

        return phoneMessageDataLoginEntity;
    }

    /**
     * phone message data entity parse event entity
     *
     * @param phoneMsg  phone message data entity
     *
     * @return  phone message data event entity
     */
    public PhoneMessageDataEventEntity parseEvent(PhoneMessageDataEntity phoneMsg) {

        PhoneMessageDataEventEntity phoneMessageDataEventEntity = new PhoneMessageDataEventEntity();
        if (phoneMsg == null) {
            return null;
        }

        if (PhoneConstant.PHONE_DATA_TYPE_EVENT != phoneMsg.getData()[0]) {
            log.warn("phone msg not event {}", phoneMsg.getData()[0]);
            return null;
        }

        phoneMessageDataEventEntity.setDeviceStatus(phoneMsg.getData()[1]);
        System.arraycopy(phoneMsg.getData(), 2, phoneMessageDataEventEntity.getDate(), 0, 7);
        phoneMessageDataEventEntity.setEvent((short)(((phoneMsg.getData()[9] & 0x00FF) << 8) | (0x00FF & phoneMsg.getData()[10])));
        phoneMessageDataEventEntity.setOperator(phoneMsg.getData()[11]);
        phoneMessageDataEventEntity.setZone((short)(((phoneMsg.getData()[13] & 0x00FF) << 8) | (0x00FF & phoneMsg.getData()[12])));

        return phoneMessageDataEventEntity;
    }

    /**
     * phone message data entity parse heart entity
     *
     * @param phoneMsg  phone message data entity
     *
     * @return  phone message data heart entity
     */
    public PhoneMessageDataHeartEntity parseHeart(PhoneMessageDataEntity phoneMsg) {

        PhoneMessageDataHeartEntity phoneMessageDataHeartEntity = new PhoneMessageDataHeartEntity();
        if (phoneMsg == null) {
            return null;
        }

        if (PhoneConstant.PHONE_DATA_TYPE_HEART != phoneMsg.getData()[0]) {
            log.warn("phone msg not heart {}", phoneMsg.getData()[0]);
            return null;
        }

        phoneMessageDataHeartEntity.setDeviceStatus(phoneMsg.getData()[1]);
        phoneMessageDataHeartEntity.setSignal(phoneMsg.getData()[2]);
        phoneMessageDataHeartEntity.setSvtg((short)(((phoneMsg.getData()[4] & 0x00FF) << 8) | (0x00FF & phoneMsg.getData()[3])));
        phoneMessageDataHeartEntity.setOvtg((short)(((phoneMsg.getData()[6] & 0x00FF) << 8) | (0x00FF & phoneMsg.getData()[5])));
        phoneMessageDataHeartEntity.setBvtg((short)(((phoneMsg.getData()[8] & 0x00FF) << 8) | (0x00FF & phoneMsg.getData()[7])));
        phoneMessageDataHeartEntity.setZoneStatus((short)(((phoneMsg.getData()[10] & 0x00FF) << 8) | (0x00FF & phoneMsg.getData()[9])));

        return phoneMessageDataHeartEntity;
    }

    /**
     * phone message data entity parse cmd ack entity
     *
     * @param phoneMsg  phone message data entity
     *
     * @return  phone message data cmd ack entity
     */
    public PhoneMessageDataCmdAckEntity parseCmdAck(PhoneMessageDataEntity phoneMsg) {

        PhoneMessageDataCmdAckEntity phoneMessageDataCmdAckEntity = new PhoneMessageDataCmdAckEntity();
        if (phoneMsg == null) {
            return null;
        }

        if (PhoneConstant.PHONE_DATA_TYPE_CMD_ACK != phoneMsg.getData()[0]) {
            log.warn("phone msg not cmd ack {}", phoneMsg.getData()[0]);
            return null;
        }

        // 解析数据

        return phoneMessageDataCmdAckEntity;
    }
}
